#include "sprayAlgo.h"
#include "opencv2/opencv.hpp"
//#include "../util.h"

#define ROI_VERTEX_NUM 4 /* each roi contain 4 components:w,h,x,y */
int *roiObj = 0;	
int roiNum = 0; 	/* total number of roi items*/
//int g_total = 0; // 统计检测结果

void spraySetRoi(int* roi, int len)
{
	//printf("Set spray roi\n");
	//if (roi == 0 || len == 0) {
	//	printf("In-Algo.Total-On = %d\n", g_total);
	//	g_total = 0;
	//	return;
	//}
	assert((len % ROI_VERTEX_NUM) == 0);
	roiObj = (int*) malloc(len * sizeof(int));
	memcpy(roiObj, roi, len*sizeof(int));
	roiNum = len / ROI_VERTEX_NUM ;
}

void sprayFreeRoi()
{
	if (roiObj) {
		free(roiObj);
		roiNum = 0;
	} 
}

SprayResult* sprayCalculaton(unsigned char* data, int width, int height, int binaryThLow, int warnTh) 
{
	if (roiNum != 2) {
		printf("roi number is not 2.\n");
		return NULL;
	}

	struct SprayResult* res = (struct SprayResult*)malloc(sizeof(*res));
	cv::Mat image(height, width, CV_8UC1, data);
	std::vector<cv::Rect> rects;
	for (int i=0; i< roiNum; i++) {
		rects.push_back(cv::Rect(roiObj[i*ROI_VERTEX_NUM],
		roiObj[i*ROI_VERTEX_NUM + 1],
		roiObj[i*ROI_VERTEX_NUM + 2],
		roiObj[i*ROI_VERTEX_NUM + 3]));

	}
	cv::Mat img0 = cv::Mat(image, rects[0]);
	cv::Mat img1 = cv::Mat(image, rects[1]);
	res->constantNumber = 1000;
	res->totalNum0 = rects[0].width * rects[0].height;
	res->totalNum1 = rects[1].width * rects[1].height;
	res->numerator = 0;

	cv::Mat med0, med1, diff0, diff1, thrshdImg0, thrshdImg1;
	cv::medianBlur(img0, med0, 3);
	cv::medianBlur(img1, med1, 3);
	cv::absdiff(img0, med0, diff0);
	cv::absdiff(img1, med1, diff1);
	cv::threshold(diff0, thrshdImg0, binaryThLow, 255, CV_THRESH_BINARY);
	cv::threshold(diff1, thrshdImg1, binaryThLow, 255, CV_THRESH_BINARY);
	for (int i = 0; i<thrshdImg0.rows; i++)
	{
		unsigned char* ptr = thrshdImg0.ptr<unsigned char>(i);
		for (int j = 0; j<thrshdImg0.cols; j++) 
		{
			if (ptr[j] == 255) 
			{
				res->numerator++;
			}
		}
	}
	float rate = 1.0* res->numerator * res->constantNumber / res->totalNum0;
	if (rate < warnTh)
	{
		res->type = spray_haze;
	}
	else {
		res->numerator = 0;
		for (int i = 0; i<thrshdImg1.rows; i++)
		{
			unsigned char* ptr = thrshdImg1.ptr<unsigned char>(i);
			for (int j = 0; j<thrshdImg1.cols; j++)
			{
				if (ptr[j] == 255)
				{
					res->numerator++;
				}
			}
		}
		float rate = 1.0* res->numerator * res->constantNumber / res->totalNum1;
		res->type =  rate > warnTh ? spray_none : spray_haze;
	}

	//if (res->type != spray_none) {
	//	g_total++;
	//}

	return res;
}
	
void sprayFreeResult(SprayResult* output)
{
	if (output) {
		free(output);
		output = 0;
	}
}

void sprayFree()
{
	if (roiObj) {
		free(roiObj);
		roiObj = 0;
	}
}